IStream - Compound File Implementation
The IStream
interface supports reading and writing data to stream objects. Stream objects
contain the data in a structured storage object, where storages provide the
structure. Simple data can be written directly to a stream, but most
frequently, streams are elements nested within a storage object. They are
similar to standard files.
The
specification of IStream defines more functionality that the OLE
implementation supports. For example, the IStream interface defines
streams up to 264 bytes in length requiring a 64-bit seek pointer.
However, the OLE implementation only supports streams up to 232 bytes in
length and read and write operations are always limited to 232 bytes at a
time. The OLE implementation also does not support stream transactioning or
region locking.
When you want
to create a simple stream based on global memory, you can get an IStream
pointer by calling the API function CreateStreamOnHGlobal
When to Use
Call the
methods of IStream to read and write data to a stream.
Since stream
objects can be marshaled to other processes, applications can share the data in
storage objects without having to use global memory. In the OLE compound file
implementation of stream objects, the custom marshaling facilities in OLE
create a remote version of the original object in the new process when the two
processes have shared memory access. Thus, the remote version does not need to
communicate with the original process to carry out its functions.
The remote
version of the stream object shares the same seek pointer as the original
stream. If you do not want to share the seek pointer, you should use the IStream::Clone
Note If you are
creating a stream object that is larger than the heap in your machine s memory and you are using an HGLOBAL, the stream
object calls GlobalRealloc internally whenever it needs more memory.
Because GlobalRealloc always copies data from the source to the
destination, increasing a stream object from 20M to 25M, for example, consumes
immense amounts of time. This is due to the size of the increments copied and
is worsened if there is less than 45M of memory on the machine because of disk
swapping.
The preferred
solution is to implement an IStream that uses memory allocated by VirtualAlloc
instead of GlobalAlloc. This can reserve a large chunk of virtual
address space and then commit memory within that address space as required. No
data copying occurs and memory is committed only as it is needed.
Another
alternative is to call the IStream::SetSize
Remarks
IStream::Read
Reads a
specified number of bytes from the stream object into memory starting at the
current seek pointer. This implementation returns S_OK if the end of the stream
was reached during the read. (This is the same as the end of file
behavior found in the MS-DOS FAT file system.
IStream::Write
Writes a
specified number from bytes into the stream object starting at the current seek
pointer. In this implementation, stream objects are not sparse. Any fill bytes
are eventually allocated on the disk and assigned to the stream.
IStream::Seek
Changes the
seek pointer to a new location relative to the beginning of the stream, to the
end of the stream, or to the current seek pointer.
IStream::SetSize
Changes the
size of the stream object. In this implementation, there is no guarantee that
the space allocated will be contiguous
IStream::CopyTo
Copies a
specified number of bytes from the current seek pointer in the stream to the
current seek pointer in another stream.
IStream::Commit
The compound
file implementation of IStream supports opening streams only in direct mode,
not transacted mode. Therefore, the method has no effect when called other than
to flush all memory buffers to the next storage level.
In this
implementation, it does not matter if you commit changes to streams, you need
only commit changes for storage objects.
IStream::Revert
This
implementation does not support transacted streams, so a call to this method
has no effect.
IStream::LockRegion
Range-locking
is not supported by this implementation, so a call to this method has no
effect.
IStream::UnlockRegion
Removes the
access restriction on a range of bytes previously restricted with IStream::LockRegion
IStream::Stat
Retrieves the
STATSTG
IStream::Clone
Creates a new
stream object with its own seek pointer that references the same bytes as the
original stream.
See Also